/* Copyright (c) 2007 Pentaho Corporation.  All rights reserved.
 * This software was developed by Pentaho Corporation and is provided under the terms
 * of the GNU Lesser General Public License, Version 2.1. You may not use
 * this file except in compliance with the license. If you need a copy of the license,
 * please go to http://www.gnu.org/licenses/lgpl-2.1.txt. The Original Code is Pentaho
 * Data Integration.  The Initial Developer is Pentaho Corporation.
 *
 * Software distributed under the GNU Lesser Public License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or  implied. Please refer to
 * the license for the specific language governing your rights and limitations.*/

/*
 * Created on 18-mei-2003
 *
 */

package com.dc.trans.steps.binaryinput;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.pentaho.di.core.Const;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDialogInterface;
import org.pentaho.di.ui.core.widget.ColumnInfo;
import org.pentaho.di.ui.core.widget.TableView;
import org.pentaho.di.ui.core.widget.TextVar;
import org.pentaho.di.ui.trans.step.BaseStepDialog;

import com.dc.trans.steps.binaryinput.BinaryInputMeta;

public class BinaryInputDialog extends BaseStepDialog implements
		StepDialogInterface {
	private BinaryInputMeta input;
	private static Class<?> PKG = BinaryInputDialog.class;
	private static final String[] YES_NO_COMBO = new String[] {
		BaseMessages.getString(PKG,"System.Combo.No"),
		BaseMessages.getString(PKG,"System.Combo.Yes") };

	private Composite wFileComp;
	private FormData fdFileComp;

	private Label wlFilename;
	private Button wbbFilename; // Browse: add file or directory
	private Button wbaFilename; // Add or change
	private TextVar wFilename;
	private FormData fdlFilename, fdbFilename, fdbaFilename, fdFilename;

	private Label wlFilenameList;
	private TableView wFilenameList;
	private FormData fdlFilenameList, fdFilenameList;

	private Label wlFilemask;
	private Text wFilemask;
	private FormData fdlFilemask, fdFilemask;

	private Label wlSize;
	private Text wSize;
	private FormData fdlSize, fdSize;

	private Label wlEncode;
	private Button wEncode;
	private FormData fdlEncode, fdEncode;

	private Group gAccepting;// liangxin
	private Label wlAccFilenames;
	private FormData fdlAccFilenames, fdAccFilenames, fdAccepting;
	private Button wAccFilenames;
	
	private Label wlFormatMatch;
	private Button wFormatMatch;
	private FormData fdlFormatMatch, fdFormatMatch;
	
	private FormData fdlAccStep, fdAccStep;
	//private Label wlAccStep;
	//private CCombo wAccStep;
	private Label wlAccField;
	private Text wAccField;
	private FormData fdlAccField, fdAccField, wCancelEncode, wOKEncode;

	public BinaryInputDialog(Shell parent, Object in, TransMeta tr, String sname) {
		super(parent, (BaseStepMeta) in, tr, sname);
		input = (BinaryInputMeta) in;
	}

	public String open() {		
		Shell parent = getParent();
		Display display = parent.getDisplay();

		shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN | SWT.MAX);
		props.setLook(shell);
		setShellImage(shell, input);

		ModifyListener lsMod = new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				input.setChanged();
			}
		};
		changed = input.hasChanged();

		FormLayout formLayout = new FormLayout();
		formLayout.marginWidth = Const.FORM_MARGIN;
		formLayout.marginHeight = Const.FORM_MARGIN;

		shell.setLayout(formLayout);
		shell.setText(BaseMessages.getString(PKG,"BinaryInputDialog.Shell.Title")); //$NON-NLS-1$

		int middle = props.getMiddlePct();
		int margin = Const.MARGIN;

		// Stepname line
		wlStepname = new Label(shell, SWT.RIGHT);
		wlStepname.setText(BaseMessages
				.getString(PKG,"BinaryInputDialog.Stepname.Label")); //$NON-NLS-1$
		props.setLook(wlStepname);
		fdlStepname = new FormData();
		fdlStepname.left = new FormAttachment(0, 0);
		fdlStepname.right = new FormAttachment(middle, -margin);
		fdlStepname.top = new FormAttachment(0, margin);
		wlStepname.setLayoutData(fdlStepname);
		wStepname = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wStepname.setText(stepname);
		props.setLook(wStepname);
		wStepname.addModifyListener(lsMod);
		fdStepname = new FormData();
		fdStepname.left = new FormAttachment(middle, 0);
		fdStepname.top = new FormAttachment(0, margin);
		fdStepname.right = new FormAttachment(100, 0);
		wStepname.setLayoutData(fdStepname);

		wFileComp = new Composite(shell, SWT.NONE);
		props.setLook(wFileComp);

		FormLayout fileLayout = new FormLayout();
		fileLayout.marginWidth = 3;
		fileLayout.marginHeight = 3;
		wFileComp.setLayout(fileLayout);

		fdFileComp = new FormData();
		fdFileComp.left = new FormAttachment(0, 0);
		fdFileComp.top = new FormAttachment(wStepname, 0);
		fdFileComp.right = new FormAttachment(100, 0);
		fdFileComp.bottom = new FormAttachment(50, 0);
		wFileComp.setLayoutData(fdFileComp);

		// Filename line
		wlFilename = new Label(wFileComp, SWT.RIGHT);
		wlFilename.setText(BaseMessages.getString(PKG,"BinaryInputDialog.Filename.Label"));
		props.setLook(wlFilename);
		fdlFilename = new FormData();
		fdlFilename.left = new FormAttachment(0, 0);
		fdlFilename.top = new FormAttachment(0, 0);
		fdlFilename.right = new FormAttachment(middle, -margin);
		wlFilename.setLayoutData(fdlFilename);

		wbbFilename = new Button(wFileComp, SWT.PUSH | SWT.CENTER);
		props.setLook(wbbFilename);
		wbbFilename.setText(BaseMessages.getString(PKG,"System.Button.Browse"));
		wbbFilename.setToolTipText(BaseMessages.getString(PKG,"System.Tooltip.BrowseForFileOrDirAndAdd"));
		fdbFilename = new FormData();
		fdbFilename.right = new FormAttachment(100, 0);
		fdbFilename.top = new FormAttachment(0, 0);
		wbbFilename.setLayoutData(fdbFilename);

		wbaFilename = new Button(wFileComp, SWT.PUSH | SWT.CENTER);
		props.setLook(wbaFilename);
		wbaFilename.setText(BaseMessages.getString(PKG,"BinaryInputDialog.FilenameAdd.Button"));
		wbaFilename.setToolTipText(BaseMessages.getString(PKG,"BinaryInputDialog.FilenameAdd.Tooltip"));
		fdbaFilename = new FormData();
		fdbaFilename.right = new FormAttachment(wbbFilename, -margin);
		fdbaFilename.top = new FormAttachment(0, 0);
		wbaFilename.setLayoutData(fdbaFilename);

		wFilename = new TextVar(transMeta, wFileComp, SWT.SINGLE | SWT.LEFT| SWT.BORDER);
		props.setLook(wFilename);
		wFilename.addModifyListener(lsMod);
		fdFilename = new FormData();
		fdFilename.left = new FormAttachment(middle, 0);
		fdFilename.right = new FormAttachment(wbaFilename, -margin);
		fdFilename.top = new FormAttachment(0, 0);
		wFilename.setLayoutData(fdFilename);

		wlFilemask = new Label(wFileComp, SWT.RIGHT);
		wlFilemask.setText(BaseMessages.getString(PKG,"BinaryInputDialog.Filemask.Label"));
		props.setLook(wlFilemask);
		fdlFilemask = new FormData();
		fdlFilemask.left = new FormAttachment(0, 0);
		fdlFilemask.top = new FormAttachment(wFilename, margin);
		fdlFilemask.right = new FormAttachment(middle, -margin);
		wlFilemask.setLayoutData(fdlFilemask);
		wFilemask = new Text(wFileComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		props.setLook(wFilemask);
		wFilemask.addModifyListener(lsMod);
		fdFilemask = new FormData();
		fdFilemask.left = new FormAttachment(middle, 0);
		fdFilemask.top = new FormAttachment(wFilename, margin);
		fdFilemask.right = new FormAttachment(wbaFilename, -margin);
		wFilemask.setLayoutData(fdFilemask);

		// Filename list line
		wlFilenameList = new Label(wFileComp, SWT.RIGHT);
		wlFilenameList.setText(BaseMessages.getString(PKG,"BinaryInputDialog.FilenameList.Label"));
		props.setLook(wlFilenameList);
		fdlFilenameList = new FormData();
		fdlFilenameList.left = new FormAttachment(0, 0);
		fdlFilenameList.top = new FormAttachment(wFilemask, margin);
		fdlFilenameList.right = new FormAttachment(middle, -margin);

		wlFilenameList.setLayoutData(fdlFilenameList);

		ColumnInfo[] colinfo = new ColumnInfo[3];
		colinfo[0] = new ColumnInfo(BaseMessages.getString(PKG,"BinaryInputDialog.FileDir.Column"),ColumnInfo.COLUMN_TYPE_TEXT, false);
		colinfo[0].setUsingVariables(true);
		colinfo[1] = new ColumnInfo(BaseMessages.getString(PKG,"BinaryInputDialog.Wildcard.Column"),ColumnInfo.COLUMN_TYPE_TEXT, false);
		colinfo[1].setToolTip(BaseMessages.getString(PKG,"BinaryInputDialog.Wildcard.Tooltip"));
		colinfo[2] = new ColumnInfo(BaseMessages.getString(PKG,"BinaryInputDialog.Required.Column"),ColumnInfo.COLUMN_TYPE_CCOMBO, YES_NO_COMBO);
		colinfo[2].setToolTip(BaseMessages.getString(PKG,"BinaryInputDialog.Required.Tooltip"));

		wFilenameList = new TableView(transMeta, wFileComp, SWT.FULL_SELECTION| SWT.SINGLE | SWT.BORDER, colinfo, input.getFileName().length,lsMod, props);
		props.setLook(wFilenameList);
		fdFilenameList = new FormData();
		fdFilenameList.left = new FormAttachment(middle, 0);
		fdFilenameList.right = new FormAttachment(100, -margin);
		fdFilenameList.top = new FormAttachment(wFilemask, margin);
		fdFilenameList.bottom = new FormAttachment(100, -margin);
		wFilenameList.setLayoutData(fdFilenameList);

		// --liangxin
		gAccepting = new Group(shell, SWT.SHADOW_ETCHED_IN);
		gAccepting.setText(BaseMessages.getString(PKG,"BinaryInputDialog.AnotherGroup.Label")); //$NON-NLS-1$;
		FormLayout acceptingLayout = new FormLayout();
		acceptingLayout.marginWidth = 3;
		acceptingLayout.marginHeight = 3;
		gAccepting.setLayout(acceptingLayout);

		fdAccepting = new FormData();
		fdAccepting.top = new FormAttachment(wFileComp, 0);
		fdAccepting.left = new FormAttachment(middle, 0);
		fdAccepting.right = new FormAttachment(100, 0);
		// fdAccepting.bottom = new FormAttachment(wlSize, 0);
		gAccepting.setLayoutData(fdAccepting);

		props.setLook(gAccepting);

		wlAccFilenames = new Label(gAccepting, SWT.RIGHT);
		wlAccFilenames.setText(BaseMessages.getString(PKG,"BinaryInputDialog.AnotherGroup.Label"));
		props.setLook(wlAccFilenames);
		fdlAccFilenames = new FormData();
		fdlAccFilenames.top = new FormAttachment(0, margin);
		fdlAccFilenames.left = new FormAttachment(0, 0);
		fdlAccFilenames.right = new FormAttachment(middle, -margin);
		wlAccFilenames.setLayoutData(fdlAccFilenames);

		wAccFilenames = new Button(gAccepting, SWT.CHECK);
		wAccFilenames.setToolTipText(BaseMessages.getString(PKG,"BinaryInputDialog.AcceptFilenames.Tooltip"));
		props.setLook(wAccFilenames);
		fdAccFilenames = new FormData();
		fdAccFilenames.top = new FormAttachment(0, margin);
		fdAccFilenames.left = new FormAttachment(middle, 0);
		fdAccFilenames.right = new FormAttachment(100, 0);
		wAccFilenames.setLayoutData(fdAccFilenames);
		wAccFilenames.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				// setFlags();
			}
		});

		// Which step to read from?
		/*
		wlAccStep = new Label(gAccepting, SWT.RIGHT);
		wlAccStep.setText(Messages
				.getString("ExcelInputDialog.AcceptStep.Label"));
		props.setLook(wlAccStep);
		fdlAccStep = new FormData();
		fdlAccStep.top = new FormAttachment(wAccFilenames, margin);
		fdlAccStep.left = new FormAttachment(0, 0);
		fdlAccStep.right = new FormAttachment(middle, -margin);
		wlAccStep.setLayoutData(fdlAccStep);	
		wAccStep = new CCombo(gAccepting, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wAccStep.setToolTipText(Messages
				.getString("ExcelInputDialog.AcceptStep.Tooltip"));
		props.setLook(wAccStep);
		fdAccStep = new FormData();
		fdAccStep.top = new FormAttachment(wAccFilenames, margin);
		fdAccStep.left = new FormAttachment(middle, 0);
		fdAccStep.right = new FormAttachment(100, 0);
		wAccStep.setLayoutData(fdAccStep);

		StepMeta[] prevSteps = transMeta.getPrevSteps(transMeta
				.findStep(stepname));
		for (int i = 0; i < prevSteps.length; i++) {
			String name = prevSteps[i].getName();
			wAccStep.add(name);
		}
		*/

		// Which field?
		//
		wlAccField = new Label(gAccepting, SWT.RIGHT);
		wlAccField.setText(BaseMessages.getString(PKG,"ExcelInputDialog.AcceptField.Label"));
		props.setLook(wlAccField);
		fdlAccField = new FormData();
		fdlAccField.top = new FormAttachment(wlAccFilenames, margin);
		fdlAccField.left = new FormAttachment(0, 0);
		fdlAccField.right = new FormAttachment(middle, -margin);
		wlAccField.setLayoutData(fdlAccField);
		wAccField = new Text(gAccepting, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wAccField.setToolTipText(BaseMessages.getString(PKG,"ExcelInputDialog.AcceptField.Tooltip"));
		props.setLook(wAccField);
		fdAccField = new FormData();
		fdAccField.top = new FormAttachment(wlAccFilenames, margin);
		fdAccField.left = new FormAttachment(middle, 0);
		fdAccField.right = new FormAttachment(100, 0);
		wAccField.setLayoutData(fdAccField);

		// --liangxin

		wlSize = new Label(shell, SWT.RIGHT);
		wlSize.setText(BaseMessages.getString(PKG,"DataPackDialog.SizeLimit.Label"));
		props.setLook(wlSize);
		fdlSize = new FormData();
		fdlSize.top = new FormAttachment(gAccepting, margin);
		fdlSize.left = new FormAttachment(0, 0);
		fdlSize.right = new FormAttachment(middle, -margin);
		wlSize.setLayoutData(fdlSize);
		wSize = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		props.setLook(wSize);
		wSize.addModifyListener(lsMod);
		fdSize = new FormData();
		fdSize.top = new FormAttachment(gAccepting, margin);
		fdSize.left = new FormAttachment(middle, 0);
		fdSize.right = new FormAttachment(100, 0);
		wSize.setLayoutData(fdSize);
		

		//-------liangxin
		
		wlEncode = new Label(shell, SWT.RIGHT);
		wlEncode.setText(BaseMessages.getString(PKG,"DataPackDialog.Encode.Label"));
		props.setLook(wlEncode);
		fdlEncode = new FormData();
		fdlEncode.left = new FormAttachment(0, 0);
		fdlEncode.top = new FormAttachment(wSize, margin);
		fdlEncode.right = new FormAttachment(middle, -margin);
		wlEncode.setLayoutData(fdlEncode);
		wEncode = new Button(shell, SWT.CHECK);
		props.setLook(wEncode);
		fdEncode = new FormData();
		fdEncode.left = new FormAttachment(middle, 0);
		fdEncode.top = new FormAttachment(wSize, margin);
		fdEncode.right = new FormAttachment(100, 0);
		wEncode.setLayoutData(fdEncode);
		
		//liangxin
		wlFormatMatch = new Label(shell, SWT.RIGHT);
		wlFormatMatch.setText(BaseMessages.getString(PKG,"DataPackDialog.FormatMatch.Label"));
		props.setLook(wlFormatMatch);
		fdlFormatMatch = new FormData();
		fdlFormatMatch.left = new FormAttachment(0, 0);
		fdlFormatMatch.top = new FormAttachment(wEncode, margin);
		fdlFormatMatch.right = new FormAttachment(middle, -margin);
		wlFormatMatch.setLayoutData(fdlFormatMatch);
		wFormatMatch = new Button(shell, SWT.CHECK);
		props.setLook(wFormatMatch);
		fdFormatMatch = new FormData();
		fdFormatMatch.left = new FormAttachment(middle, 0);
		fdFormatMatch.top = new FormAttachment(wEncode, margin);
		fdFormatMatch.right = new FormAttachment(100, 0);
		wFormatMatch.setLayoutData(fdFormatMatch);
		
		// Some buttons
		wOK = new Button(shell, SWT.PUSH);
		wOK.setText(BaseMessages.getString("System.Button.OK")); //$NON-NLS-1$
		wCancel = new Button(shell, SWT.PUSH);
		wCancel.setText(BaseMessages.getString("System.Button.Cancel")); //$NON-NLS-1$
		setButtonPositions(new Button[] { wOK, wCancel }, margin, null);

		// Add listeners
		lsCancel = new Listener() {
			public void handleEvent(Event e) {
				cancel();
			}
		};
		lsOK = new Listener() {
			public void handleEvent(Event e) {
				ok();
			}
		};
		wCancel.addListener(SWT.Selection, lsCancel);
		wOK.addListener(SWT.Selection, lsOK);
		lsDef = new SelectionAdapter() {
			public void widgetDefaultSelected(SelectionEvent e) {
				ok();
			}
		};
		wStepname.addSelectionListener(lsDef);

		// Detect X or ALT-F4 or something that kills this window...
		shell.addShellListener(new ShellAdapter() {
			public void shellClosed(ShellEvent e) {
				cancel();
			}
		});

		SelectionAdapter selA = new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				wFilenameList.add(new String[] { wFilename.getText(),wFilemask.getText() });
				wFilename.setText("");
				wFilemask.setText("");
				wFilenameList.removeEmptyRows();
				wFilenameList.setRowNums();
				wFilenameList.optWidth(true);
			}
		};
		wbaFilename.addSelectionListener(selA);
		wFilename.addSelectionListener(selA);

		// Listen to the Browse... button
		wbbFilename.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (wFilemask.getText() != null&& wFilemask.getText().length() > 0) {
					DirectoryDialog dialog = new DirectoryDialog(shell,SWT.OPEN);
					if (wFilename.getText() != null) {
						String fpath = transMeta.environmentSubstitute(wFilename.getText());
						dialog.setFilterPath(fpath);
					}
					if (dialog.open() != null) {
						String str = dialog.getFilterPath();
						wFilename.setText(str);
					}
				} else {
					FileDialog dialog = new FileDialog(shell, SWT.OPEN);
					dialog.setFilterExtensions(new String[] { "*.jpg", "*" });
					if (wFilename.getText() != null) {
						String fname = transMeta.environmentSubstitute(wFilename.getText());
						dialog.setFileName(fname);
					}
					if (dialog.open() != null) {
						String str = dialog.getFilterPath()+ System.getProperty("file.separator")+ dialog.getFileName();
						wFilename.setText(str);
					}
				}
			}
		});
		// Set the shell size, based upon previous time...
		setSize();
		getData(input);
		input.setChanged(changed);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		return stepname;
	}

	/**
	 * Copy information from the meta-data input to the dialog fields.
	 */
	public void getData(BinaryInputMeta meta) {
		wStepname.selectAll();
		if (input.getFileName() != null) {
			wFilenameList.removeAll();
			for (int i = 0; i < input.getFileName().length; i++) {
				wFilenameList.add(new String[] { input.getFileName()[i],input.getFileMask()[i], input.getFileRequired()[i] });
			}
			wFilenameList.removeEmptyRows();
			wFilenameList.setRowNums();
			wFilenameList.optWidth(true);
		}
		wSize.setText("" + input.getSizeLimit());
		wEncode.setSelection(input.isEncode());
		//liangxin
		wFormatMatch.setSelection(input.isFormatMatch());
		wAccFilenames.setSelection(meta.isAcceptingFilenames());
		
		if (meta.getAcceptingField() != null)
			wAccField.setText(meta.getAcceptingField());
		//if (meta.getAcceptingStep() != null)
		//	wAccStep.setText(meta.getAcceptingStep().getName());
	}

	private void cancel() {
		stepname = null;
		input.setChanged(changed);
		dispose();
	}

	private void ok() {
		if (Const.isEmpty(wStepname.getText()))
			return;
		getInfo(input);
		dispose();
	}

	private void getInfo(BinaryInputMeta meta) {
		stepname = wStepname.getText(); // return value
		// copy info to TextFileInputMeta class (input)
		meta.setFileName(wFilenameList.getItems(0));
		meta.setFileMask(wFilenameList.getItems(1));
		meta.setFileRequired(wFilenameList.getItems(2));
		meta.setSizeLimit(Const.toInt(wSize.getText(), 0));
		meta.setEncode(wEncode.getSelection());

		// liangxin
		meta.setAcceptingFilenames(wAccFilenames.getSelection());
		meta.setAcceptingField(wAccField.getText());
		meta.setFormatMatch(wFormatMatch.getSelection());
		
		//meta.setAcceptingStep(transMeta.findStep(wAccStep.getText()));
	}
}
